package oralExamSchedulingSystemTest;




import oralExamSchedulingSystem.IO;

import junit.framework.*;
import org.junit.Test;
import org.junit.After;
import org.junit.Before;




import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;




public class TestIO extends TestCase 
{

        private IO io;
        

        private String receivedInput;
        private String[] actualOutput;
        private String actualInput;
        
        
        private ByteArrayOutputStream out;
        private InputStream in;
        public TestIO(String name)
        {
                super(name);
        }

        @Before
        public void setUp() throws Exception 
        {
                
        }

        @After
        public void tearDown() throws Exception 
        {
        }
        
        private void setInOutStream(){  
                // set a test output
                out = new ByteArrayOutputStream();
        System.setOut(new PrintStream(out));
     
 
        // set a test input
                in = new ByteArrayInputStream(actualInput.getBytes());
                System.setIn(in);
        
        }
        
        private void getScreenResult() throws IOException
        {
                

       
        
                // get the actual screen output
        out.flush();  
        String whatWasPrinted = new String(out.toByteArray());
        actualOutput = whatWasPrinted.split(System.getProperty("line.separator"));  
        
     
           
                
        }

                
                
        




        @Test
        public void testGetReportingRoomNumber_404() throws IOException 
        {
                io= new IO();
                String expectedOutput="Input the Reporting Room Number: ";
                String expectedInput="404";
                actualInput="404";
                

                setInOutStream();
                // get the actual input
                receivedInput=io.getReportingRoomNumber();
                
                getScreenResult();
                // test the screen number of line
        assertEquals(actualOutput.length, 1);
        // test the screen output
        assertEquals(expectedOutput, actualOutput[0]);
                // test the input
                assertEquals(expectedInput, receivedInput);
        
        }
        @Test
        public void testGetReportingRoomNumber_40_404() throws IOException 
        {
                io= new IO();
                String expectedOutput="Input the Reporting Room Number: ";
                String expectedOutput2="Input the Reporting Room Number(3-4 characters): ";
                
                String expectedInput="404";
                actualInput="40 404";
                setInOutStream();
                // get the actual input
                receivedInput=io.getReportingRoomNumber();
                
                getScreenResult();

        assertEquals(actualOutput.length, 2); 
        assertEquals(expectedOutput, actualOutput[0]);
        assertEquals(expectedOutput2, actualOutput[1]);
                assertEquals(expectedInput, receivedInput);
        
        }
        @Test
        public void testGetReportingRoomNumber_40444_12_404() throws IOException 
        {
                io= new IO();
                String expectedOutput="Input the Reporting Room Number: ";
                String expectedOutput2="Input the Reporting Room Number(3-4 characters): ";
                String expectedOutput3="Input the Reporting Room Number(3-4 characters): ";
                
                String expectedInput="404";
                actualInput="40444 12 404";
                setInOutStream();
                // get the actual input
                receivedInput=io.getReportingRoomNumber();
                
                getScreenResult();

        assertEquals(actualOutput.length, 3); 
        assertEquals(expectedOutput, actualOutput[0]);
        assertEquals(expectedOutput2, actualOutput[1]);
        assertEquals(expectedOutput3, actualOutput[2]);
                assertEquals(expectedInput, receivedInput);
        
        }
        
        
        
        
        
        @Test
        public void testGetAcademicYear_2012() throws IOException 
        {
                io= new IO();
                String expectedOutput="Input the Academic Year: ";
                String expectedInput="2012";
                actualInput="2012";
                        

                setInOutStream();
        
                receivedInput=io.getAcademicYear();
                
                getScreenResult();
        
                assertEquals(actualOutput.length, 1); 
        assertEquals(expectedOutput, actualOutput[0]);
                assertEquals(expectedInput, receivedInput);
        }
        @Test
        public void testGetAcademicYear_a2B3_2013() throws IOException 
        {
                io= new IO();
                String expectedOutput="Input the Academic Year: ";
                String expectedOutput2="Input the Academic Year(4 digits): ";
                String expectedInput="2013";
                actualInput="a2B3 2013";
                        

                setInOutStream();
        
                receivedInput=io.getAcademicYear();
                
                getScreenResult();
        
                assertEquals(actualOutput.length, 2); 
        assertEquals(expectedOutput, actualOutput[0]);
        assertEquals(expectedOutput2, actualOutput[1]);
                assertEquals(expectedInput, receivedInput);
        }
        @Test
        public void testGetAcademicYear_10000_1992() throws IOException 
        {
                io= new IO();
                String expectedOutput="Input the Academic Year: ";
                String expectedOutput2="Input the Academic Year(4 digits): ";
                String expectedInput="1992";
                actualInput="10000 1992";
                        

                setInOutStream();
        
                receivedInput=io.getAcademicYear();
                
                getScreenResult();
        
                assertEquals(actualOutput.length, 2); 
        assertEquals(expectedOutput, actualOutput[0]);
        assertEquals(expectedOutput2, actualOutput[1]);
                assertEquals(expectedInput, receivedInput);
        }
        @Test
        public void testGetAcademicYear_100_100_10000_1999() throws IOException 
        {
                io= new IO();
                String expectedOutput="Input the Academic Year: ";
                String expectedOutput2="Input the Academic Year(4 digits): ";
                String expectedOutput3="Input the Academic Year(4 digits): ";
                String expectedOutput4="Input the Academic Year(4 digits): ";
                String expectedInput="1999";
                actualInput="100 100 10000 1999";
                        

                setInOutStream();
        
                receivedInput=io.getAcademicYear();
                
                getScreenResult();
        
                assertEquals(actualOutput.length, 4); 
        assertEquals(expectedOutput, actualOutput[0]);
        assertEquals(expectedOutput2, actualOutput[1]);
        assertEquals(expectedOutput3, actualOutput[2]);
        assertEquals(expectedOutput4, actualOutput[3]);
        
                assertEquals(expectedInput, receivedInput);
        }
        
        
        
        
        
        
        
        
        @Test
        public void testGetSemester_A() throws IOException 
        {
                io= new IO();
                String expectedOutput="Input the Semester: ";
                String expectedInput="A";
                actualInput="A";
                        

                setInOutStream();
        
                receivedInput=io.getSemester();
        
                getScreenResult();
                
                assertEquals(actualOutput.length, 1); 
        assertEquals(expectedOutput, actualOutput[0]);
                assertEquals(expectedInput, receivedInput);
        }
        public void testGetSemester_FirstTerm() throws IOException 
        {
                io= new IO();
                String expectedOutput="Input the Semester: ";
                String expectedInput="First Term";
                actualInput="First Term";
                        
                setInOutStream();
                
                receivedInput=io.getSemester();
        
                getScreenResult();
                
                assertEquals(actualOutput.length, 1); 
        assertEquals(expectedOutput, actualOutput[0]);
                assertEquals(expectedInput, receivedInput);
        }
        
        
        @Test
        public void testGet7RoomNumbers_402_403_405_406_407_408_411() throws IOException 
        {
                io= new IO();
                String expectedOutput1="Input the Number of Rooms: ";

                String expectedOutput2="Input the Room Numbers: ";
                LinkedList<String> expectedArrayList=new LinkedList<String>(Arrays.asList("402", "403", "405", "406", "407", "408", "411"));
                
                String actualInput="402 403 405 406 407 408 411";
                        
                // set a test output
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                System.setOut(new PrintStream(out));
     
 
        // set a test input
                InputStream  in = new ByteArrayInputStream(actualInput.getBytes());
                System.setIn(in);
                
                
                // get the actual input
                LinkedList<String> receivedArrayList=io.getRoomNumbers(7);
        
        
                // get the actual screen output
        out.flush();  
        String whatWasPrinted = new String(out.toByteArray());
        String[] linesOfOutput = whatWasPrinted.split(System.getProperty("line.separator"));  
        
        // test the screen number of line
        assertEquals(linesOfOutput.length, 2);
        
        // test the screen output
        assertEquals(expectedOutput1, linesOfOutput[0]);
        assertEquals(expectedOutput2, linesOfOutput[1]);

                // test the input
                assertEquals(true, expectedArrayList.equals(receivedArrayList));
        
        }
        @Test
        public void testGetStartTime_0830() throws IOException 
        {
                io= new IO();
                String expectedOutput="Input the Starting Time: ";
                String expectedInput="0830";
                actualInput="0830";
                           
                setInOutStream();
                
                receivedInput=io.getStartingTime();
        
                getScreenResult();
        
                assertEquals(actualOutput.length, 1); 
        assertEquals(expectedOutput, actualOutput[0]);
                assertEquals(expectedInput, receivedInput);
        }
        @Test
        public void testGetStartTime_1530() throws IOException 
        {
                io= new IO();
                String expectedOutput="Input the Starting Time: ";
                String expectedInput="1530";
                actualInput="1530";
                
                setInOutStream();
                
                receivedInput=io.getStartingTime();
        
                getScreenResult();      
                
                assertEquals(actualOutput.length, 1); 
        assertEquals(expectedOutput, actualOutput[0]);
                assertEquals(expectedInput, receivedInput);
        
        }
        @Test
        public void testGetStartTime_9999_0830() throws IOException 
        {
                io= new IO();
                String expectedOutput="Input the Starting Time: ";
                String expectedOutput2="Input the Starting Time(0830-1530): ";
                String expectedInput="0830";
                actualInput="9999 0830";
                           
                setInOutStream();
                
                receivedInput=io.getStartingTime();
        
                getScreenResult();
        
                assertEquals(actualOutput.length, 2); 
        assertEquals(expectedOutput, actualOutput[0]);
        assertEquals(expectedOutput2, actualOutput[1]);
                assertEquals(expectedInput, receivedInput);
        }
        @Test
        public void testGetStartTime_1531_0700_0900() throws IOException 
        {
                io= new IO();
                String expectedOutput="Input the Starting Time: ";
                String expectedOutput2="Input the Starting Time(0830-1530): ";
                String expectedOutput3="Input the Starting Time(0830-1530): ";
                String expectedInput="0900";
                actualInput="1531 0700 0900";
                           
                setInOutStream();
                
                receivedInput=io.getStartingTime();
        
                getScreenResult();
        
                assertEquals(actualOutput.length, 3); 
        assertEquals(expectedOutput, actualOutput[0]);
        assertEquals(expectedOutput2, actualOutput[1]);
        assertEquals(expectedOutput3, actualOutput[2]);
                assertEquals(expectedInput, receivedInput);
        }
        @Test
        public void testGetStartTime_0961_0975_930() throws IOException 
        {
                io= new IO();
                String expectedOutput="Input the Starting Time: ";
                String expectedOutput2="Input the Starting Time(0830-1530): ";
                String expectedOutput3="Input the Starting Time(0830-1530): ";
                String expectedInput="0900";
                actualInput="0961 0975 0930";
                           
                setInOutStream();
                
                receivedInput=io.getStartingTime();
        
                getScreenResult();
        
                assertEquals(actualOutput.length, 3); 
        assertEquals(expectedOutput, actualOutput[0]);
        assertEquals(expectedOutput2, actualOutput[1]);
        assertEquals(expectedOutput3, actualOutput[2]);
                assertEquals(expectedInput, receivedInput);
        }

}